package org.freemarker.web.controller;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.freemarker.core.model.Car;
import org.freemarker.core.service.CarService;
import org.freemarker.core.validator.Validator;
import org.freemarker.web.custom.CustomHttpServlet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.multipart.MultipartRequest;

@Controller
public class CopyOfCarAddController extends CustomHttpServlet {
	private final static String CAR_IMG_FOLDER = "D:\\projects\\freemarker_tut\\uploads\\cars"; // ???
																								// is
																								// there
																								// a
																								// more
																								// dynamic
																								// way

	private static final long serialVersionUID = -4559740868178370249L;

	@Autowired
	private CarService carService;
	private Validator validator = new Validator();

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {

		req.getRequestDispatcher("views/car/addCars.ftl").forward(req, resp);
	}

	@Override
	/**
	 * processes the MULTIPART request
	 * Reads the car info 
	 * Creates and saves the car if it is valid
	 * Uploads the file in the request
	 */
	protected void doPost(HttpServletRequest req, HttpServletResponse res)
			throws ServletException, IOException {

		// String marca = req.getParameter("marca");
		// String model = req.getParameter("model");
		// String numarMatricol = req.getParameter("numarMatricol");

		// Car c = new Car();
		// c.setMarca(marca);
		// c.setModel(model);
		// c.setNumarMatricol(numarMatricol);

		// upload

		FileItemFactory factory = new DiskFileItemFactory();
		ServletFileUpload upload = new ServletFileUpload(factory);

		HashMap<String, String> values = new HashMap<String, String>();
		Car car = new Car();

		try {
			List<FileItem> items = upload.parseRequest(req);
			Iterator<FileItem> iterator = items.iterator();
			while (iterator.hasNext()) {
				FileItem item = (FileItem) iterator.next();

				if (!item.isFormField()) {
					String fileName = item.getName();
					String root = getServletContext().getRealPath("/");

					// path where the file will be stored
					File path = new File(CAR_IMG_FOLDER);
					if (!path.exists()) {
						boolean status = path.mkdirs();
					}

					File uploadedFile = new File(CAR_IMG_FOLDER + "/" + fileName);
					if (!uploadedFile.exists())
						item.write(uploadedFile);
				} else {// store the name-value pairs of the form fields
					values.put(item.getFieldName(), item.getString());
				}
			}

			car.setMarca(values.get("marca"));
			car.setModel(values.get("model"));
			car.setNumarMatricol(values.get("numarMatricol"));
		} catch (FileUploadException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}

		Car c = processAddCarRequest(req, CAR_IMG_FOLDER);

		List<String> errors = new ArrayList<String>();

		try {
			errors = validator.checkCarData(c);
			try {
				if (carService.getCarForNr(c.getNumarMatricol()) != null) {
					errors.add("Plate number already in database!");
				}
			} catch (Exception e) {
				e.printStackTrace();
			}

			if (errors.size() > 0) {
				for (int i = 0; i < errors.size(); i++) {
					List<Car> cars = carService.findAll();
					req.setAttribute("cars", cars);
					req.setAttribute("errors", errors);
					req.getRequestDispatcher("views/car/listCars.ftl").forward(
							req, res);
					return;
				}
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		// Upload image
		// uploadFile(req);

		carService.save(c);
		List<Car> cars = carService.findAll();

		req.setAttribute("cars", cars);
		req.getRequestDispatcher("views/car/listCars.ftl").forward(req, res);
	}

	public Car processAddCarRequest(HttpServletRequest req, String destPath) {
		FileItemFactory factory = new DiskFileItemFactory();
		ServletFileUpload upload = new ServletFileUpload(factory);

		HashMap<String, String> values = new HashMap<String, String>();
		Car car = new Car();

		try {
			List<FileItem> items = upload.parseRequest(req);
			Iterator<FileItem> iterator = items.iterator();
			while (iterator.hasNext()) {
				FileItem item = (FileItem) iterator.next();

				if (!item.isFormField()) {
					String fileName = item.getName();
					String root = getServletContext().getRealPath("/");

					// path where the file will be stored
					File path = new File(destPath);
					if (!path.exists()) {
						boolean status = path.mkdirs();
					}

					File uploadedFile = new File(destPath + "/" + fileName);
					if (!uploadedFile.exists())
						item.write(uploadedFile);
				} else {// store the name-value pairs of the form fields
					values.put(item.getFieldName(), item.getString());
				}
			}

			car.setMarca(values.get("marca"));
			car.setModel(values.get("model"));
			car.setNumarMatricol(values.get("numarMatricol"));
		} catch (FileUploadException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return car;
	}

	/**
	 * Reads the car info from the mutlipart request
	 * 
	 * @param req
	 * @return Car with the members set to the values in the request
	 */
	public Car getCarFromRequest(HttpServletRequest req) {
		FileItemFactory factory = new DiskFileItemFactory();
		ServletFileUpload upload = new ServletFileUpload(factory);
		HashMap<String, String> values = new HashMap<String, String>();
		Car car = new Car();

		List<FileItem> items;
		try {
			items = upload.parseRequest(req);

			Iterator<FileItem> iterator = items.iterator();
			while (iterator.hasNext()) {
				FileItem item = (FileItem) iterator.next();

				if (item.isFormField()) {
					values.put(item.getFieldName(), item.getString());
				}
			}
			car.setMarca(values.get("marca"));
			car.setModel(values.get("model"));
			car.setNumarMatricol(values.get("numarMatricol"));

		} catch (FileUploadException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return car;
	}
}
